package com.ruyuan.eshop.data.migrate.tool.controller;

import com.google.common.base.Stopwatch;
import com.ruyuan.eshop.data.migrate.tool.core.JsonResult;
import com.ruyuan.eshop.data.migrate.tool.service.*;
import com.ruyuan.eshop.data.migrate.tool.task.HistoryDataSyncTask;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * 历史数据同步处理器
 * @author zhonghuashishan
 * @version 1.0
 */
@RestController
public class HistoryDataSyncController {

    private static Logger log = LoggerFactory.getLogger(HistoryDataSyncController.class);

    @Autowired
    private HistoryDataSyncService historyDataSyncService;

    @Autowired
    private TargetAfterSaleInfoService targetAfterSaleInfoService;

    @Autowired
    private TargetAfterSaleItemService targetAfterSaleItemService;

    @Autowired
    private TargetAfterSaleLogService targetAfterSaleLogService;

    @Autowired
    private TargetAfterSaleRefundService targetAfterSaleRefundService;

    @Autowired
    private TargetOrderAmountService targetOrderAmountService;

    @Autowired
    private TargetOrderAmountDetailService targetOrderAmountDetailService;

    @Autowired
    private TargetOrderAutoNoService targetOrderAutoNoService;

    @Autowired
    private TargetOrderCancelScheduledTaskService targetOrderCancelScheduledTaskService;

    @Autowired
    private TargetOrderDeliveryDetailService targetOrderDeliveryDetailService;

    @Autowired
    private TargetOrderInfoService targetOrderInfoService;

    @Autowired
    private TargetOrderItemService targetOrderItemService;

    @Autowired
    private TargetOrderPaymentDetailService targetOrderPaymentDetailService;

    @Autowired
    private TargetTendConsistencyTaskService targetTendConsistencyTaskService;

    /**
     * 默认的最小的主键ID
     */
    @Value("${ruyuan.eshop.history.data.sync.minId:0}")
    private Long minId;

    /**
     * 历史数据截止时间  eg 2021-12-31 00:00:00 = 1640880000000
     */
    @Value("${ruyuan.eshop.history.data.sync.lastGmtModified:1640880000000}")
    private long lastGmtModified;

    /**
     * 一批处理的数据量大小
     */
    @Value("${ruyuan.eshop.history.data.sync.batchSize:100}")
    private int batchSize;

    /**
     * 开启历史数据同步
     * @return
     */
    @GetMapping("/startHistoryDataSync")
    public JsonResult<Boolean> startHistoryDataSync() {

        // 防止重复执行，在本地数据库记录一个开关 TODO

        final CountDownLatch countDownLatch = new CountDownLatch(12);
        Stopwatch stopwatch = Stopwatch.createStarted();

        Date lastGmtModified_date = new Date(lastGmtModified);

        // after_sale_info表
        Long afterSaleInfoMaxId = targetAfterSaleInfoService.getMaxId();
        if(afterSaleInfoMaxId == null) {
            afterSaleInfoMaxId = minId;
        }
        log.warn("after_sale_info -> afterSaleInfoMaxId={}", afterSaleInfoMaxId);
        Thread afterSaleInfoThread = new Thread(new HistoryDataSyncTask(countDownLatch, "after_sale_info", afterSaleInfoMaxId, lastGmtModified_date, batchSize, historyDataSyncService));
        afterSaleInfoThread.setDaemon(true);
        afterSaleInfoThread.start();

        // after_sale_item表
        Long afterSaleItemMaxId = targetAfterSaleItemService.getMaxId();
        if(afterSaleItemMaxId == null) {
            afterSaleItemMaxId = minId;
        }
        log.warn("after_sale_item -> afterSaleItemMaxId={}", afterSaleItemMaxId);
        Thread afterSaleItemThread = new Thread(new HistoryDataSyncTask(countDownLatch, "after_sale_item", afterSaleItemMaxId, lastGmtModified_date, batchSize, historyDataSyncService));
        afterSaleItemThread.setDaemon(true);
        afterSaleItemThread.start();

        // after_sale_log表
        Long afterSaleLogMaxId = targetAfterSaleLogService.getMaxId();
        if(afterSaleLogMaxId == null) {
            afterSaleLogMaxId = minId;
        }
        log.warn("after_sale_log -> afterSaleLogMaxId={}", afterSaleLogMaxId);
        Thread afterSaleLogThread = new Thread(new HistoryDataSyncTask(countDownLatch,"after_sale_log", afterSaleLogMaxId, lastGmtModified_date, batchSize, historyDataSyncService));
        afterSaleLogThread.setDaemon(true);
        afterSaleLogThread.start();

        // after_sale_refund表
        Long afterSaleRefundMaxId = targetAfterSaleRefundService.getMaxId();
        if(afterSaleRefundMaxId == null) {
            afterSaleRefundMaxId = minId;
        }
        log.warn("after_sale_refund -> afterSaleRefundMaxId={}", afterSaleRefundMaxId);
        Thread afterSaleRefundThread = new Thread(new HistoryDataSyncTask(countDownLatch,"after_sale_refund", afterSaleRefundMaxId, lastGmtModified_date, batchSize, historyDataSyncService));
        afterSaleRefundThread.setDaemon(true);
        afterSaleRefundThread.start();

        // order_amount_detail表
        Long orderAmountDetailMaxId = targetOrderAmountDetailService.getMaxId();
        if(orderAmountDetailMaxId == null) {
            orderAmountDetailMaxId = minId;
        }
        log.warn("order_amount_detail -> orderAmountDetailMaxId={}", orderAmountDetailMaxId);
        Thread orderAmountDetailThread = new Thread(new HistoryDataSyncTask(countDownLatch,"order_amount_detail", orderAmountDetailMaxId, lastGmtModified_date, batchSize, historyDataSyncService));
        orderAmountDetailThread.setDaemon(true);
        orderAmountDetailThread.start();

        // order_amount表
        Long orderAmountMaxId = targetOrderAmountService.getMaxId();
        if(orderAmountMaxId == null) {
            orderAmountMaxId = minId;
        }
        log.warn("order_amount -> orderAmountMaxId={}", orderAmountMaxId);
        Thread orderAmountThread = new Thread(new HistoryDataSyncTask(countDownLatch,"order_amount", orderAmountMaxId, lastGmtModified_date, batchSize, historyDataSyncService));
        orderAmountThread.setDaemon(true);
        orderAmountThread.start();

        // order_auto_no表
        Long orderAutoNoMaxId = targetOrderAutoNoService.getMaxId();
        if(orderAutoNoMaxId == null) {
            orderAutoNoMaxId = minId;
        }
        log.warn("order_auto_no -> orderAutoNoMaxId={}", orderAutoNoMaxId);
        Thread orderAutoNoThread = new Thread(new HistoryDataSyncTask(countDownLatch,"order_auto_no", orderAutoNoMaxId, lastGmtModified_date, batchSize, historyDataSyncService));
        orderAutoNoThread.setDaemon(true);
        orderAutoNoThread.start();

        // order_cancel_scheduled_task表
        Long orderCancelScheduledMaxId = targetOrderCancelScheduledTaskService.getMaxId();
        if(orderCancelScheduledMaxId == null) {
            orderCancelScheduledMaxId = minId;
        }
        log.warn("order_cancel_scheduled_task -> orderCancelScheduledMaxId={}", orderCancelScheduledMaxId);
        Thread orderCancelScheduledTaskThread = new Thread(new HistoryDataSyncTask(countDownLatch,"order_cancel_scheduled_task", orderCancelScheduledMaxId, lastGmtModified_date, batchSize, historyDataSyncService));
        orderCancelScheduledTaskThread.setDaemon(true);
        orderCancelScheduledTaskThread.start();

        // order_delivery_detail表
        Long orderDeliveryDetailMaxId = targetOrderDeliveryDetailService.getMaxId();
        if(orderDeliveryDetailMaxId == null) {
            orderDeliveryDetailMaxId = minId;
        }
        log.warn("order_delivery_detail -> orderDeliveryDetailMaxId={}", orderDeliveryDetailMaxId);
        Thread orderDeliveryDetailThread = new Thread(new HistoryDataSyncTask(countDownLatch,"order_delivery_detail", orderDeliveryDetailMaxId, lastGmtModified_date, batchSize, historyDataSyncService));
        orderDeliveryDetailThread.setDaemon(true);
        orderDeliveryDetailThread.start();

        // order_info表
        Long orderInfoMaxId = targetOrderInfoService.getMaxId();
        if(orderInfoMaxId == null) {
            orderInfoMaxId = minId;
        }
        log.warn("order_info -> orderInfoMaxId={}", orderInfoMaxId);
        Thread orderInfoThread = new Thread(new HistoryDataSyncTask(countDownLatch, "order_info", orderInfoMaxId,
                lastGmtModified_date, batchSize, historyDataSyncService));
        orderInfoThread.setDaemon(true);
        orderInfoThread.start();

        // order_item表
        Long orderItemMaxId = targetOrderItemService.getMaxId();
        if(orderItemMaxId == null) {
            orderItemMaxId = minId;
        }
        log.warn("order_item -> orderItemMaxId={}", orderItemMaxId);
        Thread orderItemThread = new Thread(new HistoryDataSyncTask(countDownLatch,"order_item", orderItemMaxId, lastGmtModified_date, batchSize, historyDataSyncService));
        orderItemThread.setDaemon(true);
        orderItemThread.start();

        // order_payment_detail表
        Long orderPaymentDetailMaxId = targetOrderPaymentDetailService.getMaxId();
        if(orderPaymentDetailMaxId == null) {
            orderPaymentDetailMaxId = minId;
        }
        log.warn("order_payment_detail -> orderPaymentDetailMaxId={}", orderPaymentDetailMaxId);
        Thread orderPaymentDetailThread = new Thread(new HistoryDataSyncTask(countDownLatch,"order_payment_detail", orderPaymentDetailMaxId, lastGmtModified_date, batchSize, historyDataSyncService));
        orderPaymentDetailThread.setDaemon(true);
        orderPaymentDetailThread.start();

        // ruyuan_tend_consistency_task表
        Long ruyuanTendConsistencyTaskMaxId = targetTendConsistencyTaskService.getMaxId();
        if(ruyuanTendConsistencyTaskMaxId == null) {
            ruyuanTendConsistencyTaskMaxId = minId;
        }
        log.warn("ruyuan_tend_consistency_task -> ruyuanTendConsistencyTaskMaxId={}", ruyuanTendConsistencyTaskMaxId);
        Thread ruyuanTendConsistencyTaskThread = new Thread(new HistoryDataSyncTask(countDownLatch,"ruyuan_tend_consistency_task", ruyuanTendConsistencyTaskMaxId, lastGmtModified_date, batchSize, historyDataSyncService));
        ruyuanTendConsistencyTaskThread.setDaemon(true);
        ruyuanTendConsistencyTaskThread.start();

        try {
            countDownLatch.await();
            log.info("所有线程执行完毕，cost={}s", stopwatch.elapsed(TimeUnit.SECONDS));
        } catch (InterruptedException e) {
            log.error("InterruptedException", e);
        }

        return JsonResult.buildSuccess(true);

    }

}